
import java.applet.*;
// required to paint on screen
import java.awt.*;
 

// the start of an applet - HelloWorld will be the executable class
// Extends applet means that you will build the code on the standard Applet class
public class HelloWorld extends Applet
{

// The method that will be automatically called  when the applet is started
     public void init()
     {
 // It is required but does not need anything.
     }
 

// This method gets called when the applet is terminated
// That's when the user goes to another page or exits the browser.
     public void stop()
     {
     // no actions needed here now.
     }
 

// The standard method that you have to use to paint things on screen
// This overrides the empty Applet method, you can't called it "display" for example.

     public void paint(Graphics g)
     {
 //method to draw text on screen
 // String first, then x and y coordinate.
      g.drawString("Ummm, why won't it change",20,20);
      g.drawString("Hellooow World",20,40);

     }

	public static AForceEnv field;
	public static Dashboard dashboard;
	public static Clicker clicker = new Clicker();
	int mystatus;
	String lastmap;

	private ScoreBoard scoreboard = ScoreBoard.getInstance();
	public static Display frame;


	// Because this object is Serializable because it extends JComponent
	private static final long serialVersionUID = 7526471155622776147L;


	public static void main(String[] args)
	{
		Printer.printIntro();

		Printer.info.println("INFO: Starting Application...");
		AForce game = new AForce();
		Printer.info.println("INFO: Loading Images...");
		Images.loadimages();

		Printer.info.println("INFO: Setting Map based on executation time arguments...");
		String mapname;
		if(args.length > 0) mapname = args[0];
		else mapname = "Standard";

		game.newlevel(mapname);
	}

	public static void pause()
	{
		if(!clicker.isRunning())
		{
			clicker.start();
			frame.start();
		}
		else
		{
			clicker.stop();
		}
	}

	public HelloWorld()
	{

		// remember, the env should have space for the paths on the right and bottom
		//  if ships start driving off the map, check these numbers again!
		Printer.info.println("INFO: Creating the environment...");
		field = new AForceEnv(new Size(525,525));
		Printer.info.println("INFO: Starting the heads up display (Dashboard)...");
		dashboard = new Dashboard(new Size(745-525, 525, 525, 0));
	//	field.setAForce(this);

		Printer.info.println("INFO: Starting the display...");
		frame = new Display();

		Printer.info.println("INFO: Setting status to -1 (waiting for user start)...");
		mystatus = -1;
	}

	public void kill()
	{
		Printer.err.println("ERROR 332: Kill has been deprecated #AForce.kill()");
		destroy();
	}


	public void start()
	{
		if(field.numobjects() == 0) System.err.println("ERROR 217: Game can not be started without a map");
		else
		{
			Printer.note.println("NOTE 512: Field Map has been created");
			Printer.note.println("NOTE 824: The Game has been Started!");
			Printer.note.println("NOTE 112: Awaiting User Start!");
			if(Ship.userShip.getAILevel() > 0) clicker.start();
		}
	}

	public void loadmap(String mapname)
	{
		XMLParser xmlParser = new XMLParser("Maps/"+mapname+"/Obstacles.xml");

		while(true)
		{
			DisplayableObject obstacle = xmlParser.getDisplayableObject();
			if(obstacle == null) break;
			field.addobject(obstacle);
		}
	}

	public void nextlevel()
	{
		field.AForceEnvhelper();
		field.nextLevel();
		Printer.note.println("NOTE 218: Loading Level: "+AForceEnv.getLevel());
		newlevel(lastmap);
	}

	public void newlevel(String map)
	{
		mystatus = -1;
		// remember, some stuff was created in the AForce constructor in static main()
		if(!Printer.getState("railgunmode")) for(int x = 0; x < frame.getKeyListeners().length; x++)
			frame.removeKeyListener(frame.getKeyListeners()[x]);
		lastmap = map;
		mystatus = ObjectType.AwaitingStart;
		field.AForceEnvhelper();
		if(AForce.class.getResourceAsStream("Maps/"+map+"/Obstacles.xml") == null || AForce.class.getResourceAsStream("Maps/"+map+"/Units-Single.xml") == null)
			map = "Standard";
		loadmap(map);
		loadunits(map);
		start();
		dashboard.update();
		Thread.yield();
		try{ Thread.sleep(1); } catch(Exception e){}
	}

	public void newGame()
	{
		Printer.info.println("INFO 358: Preparing New Game");
		Ship.setUserShip(null);
		Printer.info.println("INFO 843: Stopping the Clicker");
		clicker.stop();
		Printer.info.println("INFO 838: Resetting Scores");
		field.resetScores();
		Printer.info.println("INFO 472: Resetting Level");
		field.resetLevel();
		Printer.info.println("INFO 844: Loading Map");
		newlevel(lastmap);
		Printer.info.println("INFO 645: Done Loading New Game");
	}



	public static Dashboard getDashboard()
	{
		return dashboard;
	}

	public static AForceEnv getField()
	{
		return field;
	}


	public void loadunits(String mapname)
	{

		// Add bad ships from map :)
		XMLParser xmlParser= new XMLParser("Maps/"+mapname+"/Units-Single.xml");
		while(true)
		{
			DisplayableObject unit = xmlParser.getDisplayableObject();
			if(unit == null) break;
			if(unit instanceof Ship)
			{
				field.addobject((Ship)unit);
				
				if(unit == Ship.userShip)
				{
					// Add the user ship (single player)
					Status usershipstatus = null;
					int userAILevel = 0;
					if(Ship.oldUserShip != null)
					{
						usershipstatus = Ship.oldUserShip.getStatus();
						userAILevel = Ship.oldUserShip.getAILevel();
					}
					if(usershipstatus != null && usershipstatus.getHealth() != 0)
						Ship.userShip.setstatus(usershipstatus);
					Ship.userShip.setAILevel(userAILevel);
					addUserIO(Ship.userShip);

				}
			}
			else Printer.err.println("ERROR 125: Unknown Unit Type #AForce.loadunits();");
			}
	}


	public void destroy()
	{
		clicker = null;
		//frame.dispose();  // TODO: dispose of frame in threadsafe way
		Printer.err.println("ERROR 342: The Game has been KILLED #AForce.destroy()");
		System.out.print("exit\n"); // so the console won't appear on AForceConsole line
		System.exit(1);
	}




	public void addUserIO(Ship usership)
	{
		UserIO userio = new UserIO();
		frame.addKeyListener(userio);
		userio.addship(usership);
	}


	public static Display getFrame()
	{
		return frame;
	}

	public ScoreBoard getScoreBoard()
	{
		return scoreboard;
	}

	public static Clicker getClicker()
	{
		return clicker;
	}


}
  